package com.hnjfzn.common.security.utils;

import com.hnjfzn.common.core.text.Convert;
import com.hnjfzn.common.core.utils.SaltUtil;
import com.hnjfzn.common.core.utils.uuid.IdUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.jcajce.provider.digest.MD5;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.hnjfzn.common.core.constant.SecurityConstants;
import com.hnjfzn.common.core.constant.TokenConstants;
import com.hnjfzn.common.core.context.SecurityContextHolder;
import com.hnjfzn.common.core.utils.ServletUtils;
import com.hnjfzn.common.core.utils.StringUtils;
import com.hnjfzn.system.api.model.LoginUser;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 权限获取工具类

 */
public class SecurityUtils
{
    /**
     * 获取用户ID
     */
    public static Long getUserId()
    {
        return SecurityContextHolder.getUserId();
    }

    /**
     * 获取用户名称
     */
    public static String getUsername()
    {
        return SecurityContextHolder.getUserName();
    }

    /**
     * 获取用户key
     */
    public static String getUserKey()
    {
        return SecurityContextHolder.getUserKey();
    }

    /**
     * 请求系统
     * @return 系统编码
     */
    public static String currentSys() {
        return currentSys(ServletUtils.getRequest());
    }

    /**
     * 请求系统
     *
     * @param request 请求
     * @return 结果
     */
    public static String currentSys(HttpServletRequest request)
    {
        return request.getHeader(SecurityConstants.CURRENT_SYSTEM);
    }

    /**
     * 获取登录系统
     */
    public static Long getSystem() {
        Long sys = null;
        String code = currentSys();
        if (StringUtils.isNotBlank(code)) {
            LoginUser user = getLoginUser();
            if (user != null && null != user.getSystems() && !user.getSystems().isEmpty()) {
                sys = Convert.toLong(user.getSystems().get(code));
            }
        }
        if (null != sys){
            return sys;
        }
        throw new RuntimeException("未获取到相关系统");
    }

    /**
     * 获取登录用户信息
     */
    public static LoginUser getLoginUser()
    {
        return SecurityContextHolder.get(SecurityConstants.LOGIN_USER, LoginUser.class);
    }

    /**
     * 获取请求token
     */
    public static String getToken()
    {
        return getToken(ServletUtils.getRequest());
    }

    /**
     * 根据request获取请求token
     */
    public static String getToken(HttpServletRequest request)
    {
        // 从header获取token标识
        String token = request.getHeader(SecurityConstants.AUTHORIZATION_HEADER);
        return replaceTokenPrefix(token);
    }

    /**
     * 裁剪token前缀
     */
    public static String replaceTokenPrefix(String token)
    {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX))
        {
            token = token.replaceFirst(TokenConstants.PREFIX, "");
        }
        return token;
    }

    /**
     * 是否为管理员
     * 
     * @param userId 用户ID
     * @return 结果
     */
    public static boolean isAdmin(Long userId)
    {
        return userId != null && 1L == userId;
    }

    /**
     * 生成BCryptPasswordEncoder密码
     *
     * @param password 密码
     * @param salt 盐值
     * @return 加密字符串
     */
    public static String encryptPassword(String password, String salt)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.encode(Md5Crypt.md5Crypt(password.getBytes(), salt));
    }

    /**
     * 判断密码是否相同
     *
     * @param rawPassword 真实密码
     * @param encodedPassword 加密后字符
     * @return 结果
     */
    public static boolean matchesPassword(String rawPassword, String encodedPassword, String salt)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(Md5Crypt.md5Crypt(rawPassword.getBytes(), salt), encodedPassword);
    }

    public static void main(String[] args){
        String salt = SaltUtil.generateSalt();
        System.out.println(salt);
        System.out.println(SecurityUtils.encryptPassword("0c909a141f1f2c0a1cb602b0b2d7d050", salt));
    }
}
